package com.sgq.vue.service.system.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sgq.vue.annotation.PlateDB;
import com.sgq.vue.dao.system.RoleMapper;
import com.sgq.vue.dao.system.UserMapper;
import com.sgq.vue.entity.system.Permission;
import com.sgq.vue.dao.system.PermissionMapper;
import com.sgq.vue.entity.system.Role;
import com.sgq.vue.entity.system.User;
import com.sgq.vue.service.system.PermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sgq.vue.utils.system.MenuTree;
import com.sgq.vue.vo.query.PermissionQueryVo;
import com.sgq.vue.vo.query.RolePermissionVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author SGQ
 * @since 2023-10-30
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;


    @Override
    public List<Permission> findPermissionListByUserId(Long userId) {
        return permissionMapper.selectPermissionListByUserId(userId);
    }

    /**
     * 按条件获取权限集合
     * @param permissionQueryVo
     * @return
     */
    @Override
    public List<Permission> findPermissionList(PermissionQueryVo permissionQueryVo) {

        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.orderByAsc(Permission::getOrderNum);
        //按顺序把所有权限获取
        List<Permission> permissions = this.baseMapper.selectList(queryWrapper);
        //把查询的权限交个MenuTree构建菜单树
        List<Permission> permissionTree = MenuTree.makeMenuTree(permissions, 0L);
        //返回菜单树
        return permissionTree;
    }

    /**
     * 构建权限列表树
     * @return
     */
    @Override
    public List<Permission> findParentPermissionList() {

        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.orderByAsc(Permission::getOrderNum);

        List<Permission> permissions = this.baseMapper.selectList(queryWrapper);

        Permission permission = new Permission();

        permission.setId(0L);

        permission.setParentId(-1L);

        permission.setLabel("根菜单");

        permissions.add(permission);

        List<Permission> permissionTree = MenuTree.makeMenuTree(permissions, -1L);

        return permissionTree;
    }

    @Override
    public boolean hasChildrenOfPermission(Long id) {
        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Permission::getParentId,id);
        Long count = this.baseMapper.selectCount(queryWrapper);
        return count > 0 ? true : false;
    }

    /**
     *  userId 找出我有哪些权限
     *  roleId 找出当前角色已经拥有的权限
     *  最后形成树形结构，对当前角色拥有的权限进行勾选（显示两个对象都有的权限）
     * @param userId
     * @param roleId
     * @return
     */
    @Override
    public RolePermissionVo findPermissionTree(Long userId, Long roleId) {
        //1.查询当前用户信息 （当前用户给角色分配权限）
        User user = userMapper.selectById(userId);
        List<Permission> list = null;
        //2.判断当前用户角色，如果是管理员，则查询所有权限；如果不是管理员，则只查询自己所拥有的的权限
        if(!ObjectUtils.isEmpty(user.getIsAdmin()) && user.getIsAdmin() == 1){
            //查询所有权限
            list = baseMapper.selectList(null);
        }else{
            //根据用户ID查询
            list = baseMapper.selectPermissionListByUserId(userId);
        }
        //3.组装成树数据（根据用户权限多少不同获得不同的菜单树结构）
        List<Permission> permissionList = MenuTree.makeMenuTree(list, 0L);
        //4.查询要分配角色的原有权限（被分配角色原本已拥有的权限）
        List<Permission> rolePermissions = baseMapper.selectPermissionListByRoleId(roleId);
        //5.找出该角色存在的数据
        List<Long> listIds = new ArrayList<Long>();
        Optional.ofNullable(list).orElse(new ArrayList<>())
                .stream()
                .filter(Objects::nonNull) //等同于 obj -> obj!=null
                .forEach(item -> {
                    Optional.ofNullable(rolePermissions).orElse(new ArrayList<>())
                            .stream()
                            .filter(Objects::nonNull)
                            .forEach(obj ->{
                                if(item.getId().equals(obj.getId())){
                                    listIds.add(obj.getId());
                                    return;
                                }
                            });
                });
        //创建
        RolePermissionVo vo = new RolePermissionVo();
        vo.setPermissionList(permissionList);
        vo.setCheckList(listIds.toArray());
        return vo;
    }

    /**
     * 在添加新的权限时把新的权限给到Admin
     * @param permission
     * @return
     */
    @Override
    @PlateDB(value = "add")
    @Transactional
    public Permission saveAndUpdateAdminPermission(Permission permission) {
        this.baseMapper.insert(permission);
        Long permissionId = permission.getId();
        List<Long> permissionIds = new ArrayList<>();
        permissionIds.add(permissionId);
        //找到所有超级管理员的ID
        LambdaQueryWrapper<Role> roleWrapper = new LambdaQueryWrapper<>();
        roleWrapper.eq(Role::getRoleCode,"ROLE_SYSTEM");
        List<Role> roles = roleMapper.selectList(roleWrapper);
        //记录插入次数
        int count = 0;
        for (Role role : roles) {
            Long roleId = role.getId();
            int save = roleMapper.saveRolePermission(roleId, permissionIds);
            count += save;
        }
        return permission;
    }

    @Override
    @PlateDB(value = "edit")
    public Permission updateAndGet(Permission permission) {
        this.baseMapper.updateById(permission);
        System.out.println("permission2222 = " + permission);
        return permission;
    }

    @Override
    @PlateDB(value = "delete")
    public Permission deleteAndGet(Long id) {
        Permission permission = this.baseMapper.selectById(id);
        this.baseMapper.deleteById(id);
        return permission;
    }
}
